<?php
class Project{
	private $o = array();
	private $v = array();
	
	static public $type = array();
	static public $process_type = array('无', '借款', '报销', '冲账', '捐赠');
	static public $status = array('未开始','进行中','已结束');
	
	static public $process_type_operator = array('', '-', '-', '+', '+');
	
	public function __construct($id = 0){
		global $db;
		if($id > 0){
			$db->select_table('project');
			$this->o = $this->v = $db->FETCH('*', 'id='.$id);
		}
	}
	
	public function __destruct(){
		global $db;
		if($this->o['id']){
			$update = array_diff_update($this->o, $this->v);
			unset($update['id']);
			if($update){
				$db->select_table('project');
				$db->UPDATE($update, 'id='.$this->o['id']);
			}
		}
	}
	
	public function exists(){
		return isset($this->v['id']) && $this->v['id'] > 0;
	}
	
	public function fetchByCode($code){
		global $db;
		$db->select_table('project');
		$this->o = $this->v = $db->FETCH('*', '`code`='.intval($code));	
		return (bool) $this->v;
	}
	public function fetchById($id){
		global $db;
		$db->select_table('project');
		$this->o = $this->v = $db->FETCH('*', '`id`='.intval($id));	
		return (bool) $this->v;
	}
	public static function amountSum(){
		global $db,$tpre;
		$db->select_table('project');
		return intval($db->result_first("SELECT SUM(`amount`) FROM {$tpre}project"));
	}
	public static function restamountSum(){
		global $db,$tpre;
		$db->select_table('project');
		return intval($db->result_first("SELECT SUM(`restamount`) FROM {$tpre}project"));
	}
	public function fetchByProcessId($id){
		global $db;
		$db->select_table('projectprocess');
		$id = $db->SRESULT('pid', 'id='.intval($id));
		if($id){
			$this->o = $this->v = self::GetItemById($id);
			return true;
		}
		return false;
	}
	
	public function setProperty($property, $value = ''){
		if(is_string($property)){
			$this->v[$property] = $value;
		}elseif(is_array($property)){
			foreach($property as $k => $v){
				$this->setProperty($k, $v);
			}
		}else{
			return false;
		}
		return true;
	}
	
	public function getProperty($property){
		return $this->v[$property];
	}
	
	public function uploadAttachment($info){
		if(!$_FILES[$info]){
			return false;
		}
	
		$tmp = pathinfo($_FILES[$info]['name']);
		$path = './data/attachment/'.$info.'_'.$this->v['id'].'.'.$tmp['extension'];
		
		if(!move_uploaded_file($_FILES[$info]['tmp_name'], $path)){
			return false;
		}
		
		$this->v[$info] = $path;
		
		return true;
	}
	
	public function addProcess($data){
		global $db, $_G;
		
		if(!$this->v['id'] || $data['amount'] == 0){
			return false;
		}else{
			$db->select_table('projectprocess');
			
			$data['pid'] = $this->v['id'];
			//$db->INSERT(array('pid' => $this->v['id'], 'amount' => intval($amount), 'reason' => raddslashes($reason), 'dateline' => $_G['timestamp']));
			$db->INSERT($data);
			if($db->insert_id()){
				$datatype = $data['type'];
				
				if(self::$process_type_operator[$datatype] == '+'){
					$this->v['restamount'] += $data['amount'];
					
					if($data['type'] == 4){//捐赠
						$this->v['amount'] += $data['amount'];
					}
					
				}else if(self::$process_type_operator[$datatype] == '-'){
					$this->v['restamount'] -= $data['amount'];
				}
			}
		}
	}
	
	public function deleteProcess($processid){
		global $db;
		
		$processid = intval($processid);
		
		$db->select_table('projectprocess');
		$process = $db->FETCH('*', '`id`='.$processid);
		
		//对于冲账的应该减，对于报销的应该加
		$datatype = $process['type'];
		if(self::$process_type_operator[$datatype] == '-'){
			$this->v['restamount'] += $process['amount'];
		
		}else if(self::$process_type_operator[$datatype] == '+'){
			$this->v['restamount'] -= $process['amount'];
						
			if($process['type'] == 4){//捐赠
				$this->v['amount'] -= $process['amount'];
			}
		}
		
		$db->DELETE('`id`='.$processid);

		return $db->affected_rows();
	}

	public function toArray(){
		return $this->v;
	}
	
	public function toReadableArray(){
		return self::ConvertToReadable($this->v);
	}
	
	public function insertIntoDatabase(){
		unset($this->v['id']);
		return self::insertItem($this->v);
	}
	
	public function getProcess($force_refresh = false){
		global $db;
		
		if(!$this->v['id']){
			return NULL;
		}
		
		if(isset($this->v['process']) && !$force_refresh){
			return $this->v['process'];
		}else{
			$db->select_table('projectprocess');
			return $this->v['process'] = $db->MFETCH('*', '`pid`='.intval($this->v['id']));
		}
	}
	
	static public function GetItemById($id){
		global $db,$tpre;
		$result = $db->fetch_first("SELECT * FROM {$tpre}project WHERE id=$id");
		return $result;
	}
	static public function GetItemByType($type, $offset = 0, $limit = 1){
		global $db,$tpre;
		$type = intval($type);
		$result = $db->fetch_all("SELECT * FROM {$tpre}project WHERE type=$type LIMIT $offset,$limit");
		return $result;
	}
	
	static public function getItemByUnusedRatio($ratio, $offset, $limit){
		global $db;
		$db->select_table('project');
		$ratio = floatval($ratio) / 100;
		return $db->MFETCH('*', "`restamount`/`amount`<=$ratio LIMIT $offset, $limit");
	}
	
	static public function getItemByDeadline($deadline_limit, $offset, $limit){
		global $db, $_G;
		$db->select_table('project');
		$deadline_limit = max(0, intval($deadline_limit) * 24 * 3600 + $_G['timestamp']);
		return $db->MFETCH('*', '`deadline`<='.$deadline_limit.' AND `deadline`>'.$_G['timestamp'].' ORDER BY deadline LIMIT '.$offset.','.$limit);
	}
	
	static public function getMaxNum($condition = '1'){
		global $db, $tpre;
		$num = $db->result_first("SELECT COUNT(*) FROM {$tpre}project WHERE $condition");
		return $num;
	}

	static public function getItemOrderByTime($item, $offset, $limit){
		global $db, $tpre;
		if(is_array($item)){
			$item = '`'.implode('`,`', $item).'`';
		}//explode为相反用法
		$result = $db->fetch_all("SELECT $item FROM {$tpre}project WHERE 1 ORDER BY dateline DESC LIMIT $offset,$limit");
		//print_r($result);
		return $result;
	}
	
	static public function getItemByMultiConditions($item, $conditions){
		global $db;

		if(is_array($conditions)){
			$conditions = implode(' AND ', $conditions);
		}
		
		$db->select_table('project');
		return $db->MFETCH($item, $conditions);
	}
	
	static public function insertItem($data){
		global $db,$tpre;
		$db->select_table('project');
		
		$dup = $db->SRESULT('id', (!empty($data['code']) ? "code='$data[code]' OR" : '') . "(name='$data[name]' AND source='$data[source]' AND sourceaccount='$data[sourceaccount]')");
		
		if($dup > 0){
			$project = new Project($dup);
			$process = array(
				'dateline' => $data['creditedtime'],
				'amount' => $data['amount'],
				'reason' => '二次捐赠',
				'type' => 4,
			);
			$project->addProcess($process);
		}else{
			$data['dateline'] = $GLOBALS['_G']['timestamp'];
		
			$db->INSERT($data);
			return $db->insert_id();
		}
	}

	static public function updateItem($data, $id){
		global $db;
		$db->select_table('project');
		$db->UPDATE($data,"id=$id");
		return $db->affected_rows();
	}

	static public function deleteItem($id){
		global $db, $tpre;
		$db->query("DELETE FROM {$tpre}project WHERE id=$id");
	}
	
	static public function convertToReadable($p){
		$type = readcache('project_type');

		$p['type'] = $type[$p['type']];
		$p['deadline'] = rgmdate($p['deadline']);
		$p['dateline'] = rgmdate($p['dateline']);
		$p['creditedtime'] = rgmdate($p['creditedtime']);
		
		return $p;
	}
	
	static public function convertToOriginal($p){
		$type = array_flip(readcache('project_type'));
		
		$p['type'] = $type[$p['type']];
		$p['deadline'] = strtotime($p['deadline']);
		$p['dateline'] = strtotime($p['dateline']);
		$p['creditedtime'] = strtotime($p['creditedtime']);
		
		return $p;
	}

	static public function isRequiredItem($item){
		static $project_can_be_empty = array(//必填项
			'code' => false,
			'name' => true,
			'type' => false,
			'source'=> true,
			'sourceaccount' => true,
			'amount' => true,
			'creditedtime' => true,
			'specifieduses' => false,
			'responsor' => false,
			'responsormobile' => false,
			'deadline'=> false
		);

		return $project_can_be_empty[$item];
	}
}

Project::$type = readcache('project_type');
Project::$type[0] = '无';

?>